package lumis.content.metadata;

import lumis.content.ContentManagerFactory;
import lumis.content.core.Content;
import lumis.content.core.ContentComment;
import lumis.content.core.ContentLocale;
import lumis.content.core.IContentManager;
import lumis.content.core.ContentPublication;
import lumis.content.core.ContentVersion;
import lumis.portal.*;
import lumis.portal.authentication.SessionConfig;
import lumis.portal.dao.hibernate.ITransactionHibernate;
import lumis.portal.manager.ManagerException;
import lumis.portal.manager.ManagerFactory;
import lumis.portal.serviceinstance.ServiceInstanceConfig;
import lumis.portal.transaction.PortalTransactionFactory;
import lumis.util.ITransaction;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import org.hibernate.Session;

/**
 * Manager for meta data
 *
 * @version $Revision: 9601 $ $Date: 2008-07-18 15:38:17 -0300 (Fri, 18 Jul 2008) $
 * @since 4.0.4
 * @deprecated Since 4.2.0, replaced by {@link IContentManager}.
 */
@Deprecated
public class MetaDataManager implements IMetaDataManager
{
	private void setMetaDataConfigServiceInstanceId(MetaDataConfig metaDataConfig, String serviceInstanceId) throws PortalException
	{
		ServiceInstanceConfig serviceInstanceConfig = ManagerFactory.getServiceInstanceManager().get(
				serviceInstanceId, PortalTransactionFactory.getCurrentTransaction());
		metaDataConfig.setServiceInstanceId(serviceInstanceId);
		metaDataConfig.setServiceId(serviceInstanceConfig.getServiceId());
	}
	
	private MetaDataConfig createMetaDataConfig(ContentVersion version) throws PortalException
	{
		ContentLocale contentLocale = version.getContentLocale();
		Content content = contentLocale.getContent();
		
		MetaDataConfig metaDataConfig = new MetaDataConfig();
		metaDataConfig.setId(version.getId());
		metaDataConfig.setCreatedBy(contentLocale.getCreatedBy());
		Date createdDateTime = contentLocale.getCreatedDateTime();
		metaDataConfig.setCreatedDateTime(createdDateTime != null ? new Timestamp(createdDateTime.getTime()) : null);
		Locale locale = contentLocale.getLocale();
		String languageId = locale != null ? locale.toString() : null;
		metaDataConfig.setLanguageId(languageId);
		metaDataConfig.setLastModifiedBy(version.getLastModifiedBy());
		Date lastModifiedDateTime = version.getLastModifiedDateTime();
		metaDataConfig.setLastModifiedDateTime(lastModifiedDateTime != null ? new Timestamp(lastModifiedDateTime.getTime()) : null);
		setMetaDataConfigServiceInstanceId(metaDataConfig, content.getServiceInstanceId());
		metaDataConfig.setLastModifiedBy(version.getLastModifiedBy());
		metaDataConfig.setPrimaryName(version.getPrimaryName());
		metaDataConfig.setSourceId(content.getSourceId());
		
		// these ids are not provided
		//metaDataConfig.setLanguageContentId(...);
		//metaDataConfig.setVersionContentId(...);
		
		return metaDataConfig;
	}
	
	private Collection<MetaDataConfig> convertContentVersionToMetaDataConfig(
			ContentVersion version, boolean single) throws PortalException
	{
		if (version.getPublications().isEmpty())
		{
			return Collections.singleton(createMetaDataConfig(version));
		}
		else
		{
			Collection<MetaDataConfig> metaDataConfigs = new ArrayList<MetaDataConfig>();
			for (ContentPublication publication: version.getPublications())
			{
				for (String serviceInstanceId: publication.getServiceInstanceIds())
					metaDataConfigs.add(convertContentPublicationToMetaDataConfig(publication, serviceInstanceId));
			}
			return metaDataConfigs;
		}
		
	}
	
	private MetaDataConfig convertContentVersionToSingleMetaDataConfig(ContentVersion version) throws PortalException
	{
		return convertContentVersionToMetaDataConfig(version, true).iterator().next();
	}
	
	private MetaDataConfig convertContentPublicationToMetaDataConfig(
			ContentPublication publication, String serviceInstanceId) throws PortalException
	{
		ContentVersion version = publication.getContentVersion();
		ContentLocale contentLocale = version.getContentLocale();
		Content content = contentLocale.getContent();
		
		MetaDataConfig metaDataConfig = createMetaDataConfig(version);
		setMetaDataConfigServiceInstanceId(metaDataConfig, content.getServiceInstanceId());
		if (!serviceInstanceId.equals(content.getServiceInstanceId()))
			metaDataConfig.setParentServiceInstanceId(content.getServiceInstanceId());
		metaDataConfig.setPublished(publication.isPublished());
		Date publishStartDateTime = publication.getPublishStartDateTime();
		metaDataConfig.setPublishEndDateTime(publishStartDateTime != null ? new Timestamp(publishStartDateTime.getTime()) : null);
		Date publishEndDateTime = publication.getPublishEndDateTime();
		metaDataConfig.setPublishEndDateTime(publishEndDateTime != null ? new Timestamp(publishEndDateTime.getTime()) : null);
		
		return metaDataConfig;
	}

	public MetaDataConfig get(SessionConfig sessionConfig, String metaDataId, ITransaction transaction) throws ManagerException, PortalException
	{
		ContentVersion version = ContentManagerFactory.getContentManager().getContentVersion(metaDataId);
		return convertContentVersionToSingleMetaDataConfig(version);
	}
	
	public Collection<MetaDataConfig> getByItemId(SessionConfig sessionConfig, String itemId, ITransaction transaction) throws ManagerException, PortalException
	{
		return getByItemId(sessionConfig, itemId, true, transaction);
	}

	public Collection<MetaDataConfig> getByItemId(SessionConfig sessionConfig, String itemId, boolean considerInactiveVersion, ITransaction transaction) throws ManagerException, PortalException
	{
		try
		{
			ContentVersion contentVersion = ContentManagerFactory.getContentManager().getContentVersionByItemId(itemId);
			return convertContentVersionToMetaDataConfig(contentVersion, false);
		}
		catch (PortalObjectNotFoundException e)
		{
			return Collections.emptyList();
		}
	}

	public Collection<MetaDataConfig> getByItemIdAndServiceId(SessionConfig sessionConfig, String itemId, String serviceId, String sourceId, ITransaction transaction) throws ManagerException, PortalException
	{
		return getByItemIdAndServiceId(sessionConfig, itemId, serviceId, sourceId, true, transaction);
	}

	public Collection<MetaDataConfig> getByItemIdAndServiceId(SessionConfig sessionConfig, String itemId, String serviceId, String sourceId, boolean considerInactiveVersion, ITransaction transaction) throws ManagerException, PortalException
	{
		return getByItemId(sessionConfig, itemId, considerInactiveVersion, transaction);
	}
	
	public MetaDataConfig getByItemIdAndServiceInstanceId(SessionConfig sessionConfig, String itemId, String serviceInstanceId, String sourceId, ITransaction transaction) throws ManagerException, PortalException
	{
		return getByItemIdAndServiceInstanceId(sessionConfig, itemId, serviceInstanceId, sourceId, true, transaction);
	}

	public MetaDataConfig getByItemIdAndServiceInstanceId(SessionConfig sessionConfig, String itemId, String serviceInstanceId, String sourceId, boolean considerInactiveVersion, ITransaction transaction) throws ManagerException, PortalException
	{
		Collection<MetaDataConfig> metaDataConfigs = getByItemId(sessionConfig, itemId, considerInactiveVersion, transaction);
		for (MetaDataConfig metaDataConfig: metaDataConfigs)
		{
			if (serviceInstanceId.equals(metaDataConfig.getServiceInstanceId()))
				return metaDataConfig;
		}
		
		return null;
	}
	
	public String getParentServiceInstanceId(SessionConfig sessionConfig, String itemId, String serviceId, ITransaction transaction) throws ManagerException, PortalException
	{
		Session session = ((ITransactionHibernate)transaction).getSession();
		return (String)session.createQuery("select v.contentLocale.content.serviceInstanceId from ContentVersion v where v.itemId = ?")
				.setString(0, itemId)
				.uniqueResult();
	}
	
	@SuppressWarnings("unchecked")
	public Collection<String> getIdsByServiceInstanceId(SessionConfig sessionConfig, String serviceInstanceId, ITransaction transaction) throws ManagerException, PortalException
	{
		Session session = ((ITransactionHibernate)transaction).getSession();
		return session.createQuery("select distinct v.id from ContentVersion v left join " +
				"v.publications p left join p.serviceInstanceIds si where " +
				"v.contentLocale.content.serviceInstanceId = :si or si = :si")
				.setString("si", serviceInstanceId)
				.list();
	}
	
	public int getNumComments(SessionConfig sessionConfig, String metaDataId, ITransaction transaction) throws ManagerException, PortalException
	{
		ContentVersion version = ContentManagerFactory.getContentManager().getContentVersion(metaDataId);
		return version.getContentLocale().getComments().size();
	}
	
	public List<CommentConfig> getComments(SessionConfig sessionConfig, String metaDataId, ITransaction transaction) throws ManagerException, PortalException
	{
		ContentVersion version = ContentManagerFactory.getContentManager().getContentVersion(metaDataId);
		List<CommentConfig> result = new ArrayList<CommentConfig>();
		List<? extends ContentComment> contentComments = version.getContentLocale().getComments();
		for (ContentComment contentComment: contentComments)
		{
			CommentConfig commentConfig = new CommentConfig();
			commentConfig.setComment(contentComment.getCommentText());
			commentConfig.setCreatedBy(contentComment.getCreatedBy());
			Date createdDateTime = contentComment.getCreatedDateTime();
			commentConfig.setCreatedDateTime(createdDateTime != null ? new Timestamp(createdDateTime.getTime()) : null);
			commentConfig.setMetaDataId(metaDataId);
			result.add(commentConfig);
		}
		return result;
	}
	
	public int getNumVersions(SessionConfig sessionConfig, String itemId, String serviceInstanceId, String sourceId, ITransaction transaction) throws ManagerException, PortalException
	{
		ContentVersion version = ContentManagerFactory.getContentManager().getContentVersionByItemId(itemId);
		if (version != null)
			return version.getContentLocale().getVersions().size();
		else
			return 0;
	}
}